package com.w3c.pragmatic.utils;

import com.w3c.pragmatic.service.IRedissonCustomer;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * 分布式锁工具类
 *
 * @author wangdong
 * @since 2021/12/17 9:38
 */
@Slf4j
public class RedissonUtil {

    // 定义静态变量（通过下面set方法注入）
    private static IRedissonCustomer redissonCustomer;

    // 通过自动装配方式注入自定义redisson封装实例
    public static void setLocker(IRedissonCustomer locker) {
        redissonCustomer = locker;
    }

    // ================================工具类方法提供==================================

    /**
     * 通过key加锁
     *
     * @param lockKey 锁键
     */
    public static void lock(String lockKey) {
        redissonCustomer.lock(lockKey);
    }

    /**
     * 通过key加锁并设置加锁时间
     *
     * @param lockKey 锁键
     * @param timeout 锁失效时间（默认秒）
     */
    public static void lock(String lockKey, int timeout) {
        redissonCustomer.lock(lockKey, timeout);
    }

    /**
     * 通过key加锁并设置加锁时间
     *
     * @param lockKey 锁键
     * @param unit    时间单位
     * @param timeout 锁失效时间
     */
    public static void lock(String lockKey, TimeUnit unit, int timeout) {
        redissonCustomer.lock(lockKey, unit, timeout);
    }

    /**
     * 尝试获取锁（获取不到等待leaseTime，获取到timeout后失效）
     *
     * @param lockKey   锁键
     * @param leaseTime 获取不到锁自旋等待时间
     * @return 最终获取锁状态
     */
    public static boolean tryLock(String lockKey, long leaseTime) {
        return tryLock(lockKey, TimeUnit.SECONDS, leaseTime);
    }

    /**
     * 尝试获取锁（获取不到等待leaseTime，获取到timeout后失效）
     *
     * @param lockKey   锁键
     * @param unit      时间单位
     * @param leaseTime 获取不到锁自旋等待时间
     * @return 最终获取锁状态
     */
    public static boolean tryLock(String lockKey, TimeUnit unit, long leaseTime) {
        try {
            return redissonCustomer.tryLock(lockKey, unit, leaseTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
            log.info("获取锁异常，异常信息：{}", e.getMessage());
        }
        return false;
    }

    /**
     * 尝试获取锁（获取不到等待leaseTime，获取到timeout后失效）
     *
     * @param lockKey   锁键
     * @param leaseTime 获取不到锁自旋等待时间
     * @param timeout   获取到锁后锁失效时间
     * @return 最终获取锁状态
     */
    public static boolean tryLock(String lockKey, long leaseTime, long timeout) {
        return tryLock(lockKey, TimeUnit.SECONDS, leaseTime, timeout);
    }

    /**
     * 尝试获取锁（获取不到等待leaseTime，获取到timeout后失效）
     *
     * @param lockKey   锁键
     * @param unit      时间单位
     * @param leaseTime 获取不到锁自旋等待时间
     * @param timeout   获取到锁后锁失效时间
     * @return 最终获取锁状态
     */
    public static boolean tryLock(String lockKey, TimeUnit unit, long leaseTime, long timeout) {
        try {
            return redissonCustomer.tryLock(lockKey, unit, leaseTime, timeout);
        } catch (InterruptedException e) {
            e.printStackTrace();
            log.info("获取锁异常，异常信息：{}", e.getMessage());
        }
        return false;
    }

    /**
     * 通过key释放锁
     *
     * @param lockKey 锁键
     */
    public static void unlock(String lockKey) {
        redissonCustomer.unlock(lockKey);
    }
}
